﻿

using Moq;
using NUnit.Framework;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using TabbedTemplate.Models;
using TabbedTemplate.Services;
using TabbedTemplate.ViewModels;

namespace UnitTest.NotTestViewModel
{
    public class TestPunchViewPageViewModel
    {
        [Test]
        public async Task TestPageAppearingCommandFunctionNotNewEdit()
        {
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            preferenceStorageMock.Setup(p => p.Get("PunchEdit", true))
                .Returns(false);

            var mockPreferenceStorage = preferenceStorageMock.Object;

            var PunchViewPageViewModel =
                new PunchViewPageViewModel(mockPreferenceStorage, null, null,
                    null, null, null);
            await PunchViewPageViewModel.PageAppearingCommandFunction();
        }

        [Test]
        public async Task TestPageAppearingCommandFunctionNewEdit()
        {
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            preferenceStorageMock.Setup(p => p.Get("PunchEdit", true))
                .Returns(true);
            var mockPreferenceStorage = preferenceStorageMock.Object;
            var punchTimeStampParameter = new PunchTimeStampParameter
            {
                PunchInfo = new PunchInfo { Content = "测试", Timestamp = 1234 }
            };
            var bytes = new List<byte[]> { new byte[1000], new byte[2000] };
            var imageServiceMock = new Mock<IImageService>();
            imageServiceMock
                .Setup(p =>
                    p.ReadImageAsync(
                        punchTimeStampParameter.PunchInfo.Timestamp))
                .ReturnsAsync(bytes);
            var mockImageService = imageServiceMock.Object;
            var PunchViewPageViewModel = new PunchViewPageViewModel(
                mockPreferenceStorage, mockImageService, null, null, null,
                null);
            PunchViewPageViewModel.PunchTimeStampParameter =
                punchTimeStampParameter;
            await PunchViewPageViewModel.PageAppearingCommandFunction();

            Assert.AreEqual(PunchViewPageViewModel.Action, "编辑");
            imageServiceMock.Verify(
                p => p.ReadImageAsync(punchTimeStampParameter.PunchInfo
                    .Timestamp), Times.Once);
            preferenceStorageMock.Verify(p => p.Set("PunchEdit", false),
                Times.Once);
            Assert.AreEqual(PunchViewPageViewModel.ImageViewModelCollection.Count,
                bytes.Count);
        }


        [Test]
        public async Task TestEditCommandFunctionEdit()
        {
            var action = "编辑";
            var punchViewPageViewModel =
                new PunchViewPageViewModel(null, null, null, null, null, null);
            punchViewPageViewModel.Action = action;
            await punchViewPageViewModel.EditCommandFunction();
            Assert.IsTrue(punchViewPageViewModel.Edit);
            Assert.IsFalse(punchViewPageViewModel.NotEdit);
            Assert.AreEqual(punchViewPageViewModel.Action, "保存");

        }

        [Test]
        public async Task TestEditCommandFunctionSave()
        {
            var punchTimeStampParameter = new PunchTimeStampParameter
            {
                PunchInfo = new PunchInfo { Content = "测试", Timestamp = 1234 }
            };
            var action = "保存";
            var imageServiceMock = new Mock<IImageService>();
            var mockImageService = imageServiceMock.Object;
            var punchInfoStorageMock = new Mock<IPunchInfoStorage>();
            var mockPunchInfoStorage = punchInfoStorageMock.Object;
            var collection = new ObservableCollection<ImageViewModel>();
            var punchViewPageViewModel =
                new PunchViewPageViewModel(null, mockImageService, null, mockPunchInfoStorage, null, null);
            var im = new ImageViewModel(null, punchViewPageViewModel);
            collection.Add(im);
            punchViewPageViewModel.ImageViewModelCollection = collection;

            punchViewPageViewModel.Action = action;
            punchViewPageViewModel.PunchTimeStampParameter =
                punchTimeStampParameter;
            await punchViewPageViewModel.EditCommandFunction();
            Assert.IsFalse(punchViewPageViewModel.Edit);
            Assert.IsTrue(punchViewPageViewModel.NotEdit);
            Assert.AreEqual(punchViewPageViewModel.Action, "编辑");
            imageServiceMock.Verify(p => p.DeleteFolder(1234), Times.Once);
            punchInfoStorageMock.Verify(p => p.SavePunchInfoAsync(punchViewPageViewModel.PunchTimeStampParameter.PunchInfo, false), Times.Once);
            Assert.IsTrue(punchViewPageViewModel.ImageViewModelCollection.Count == 1);
        }

        [Test]
        public async Task TestViewStoreCommandFunction()
        {
            var punchTimeStampParameter = new PunchTimeStampParameter
            {
                Store = new Store()
            };
            var punchNavigationServiceMock =
                new Mock<IPunchNavigationService>();
            var mockPunchNavigationService = punchNavigationServiceMock.Object;
            var punchViewPageViewModel =
                new PunchViewPageViewModel(null, null, null, null, null, mockPunchNavigationService);
            punchViewPageViewModel.PunchTimeStampParameter =
                punchTimeStampParameter;
            await punchViewPageViewModel.ViewStoreCommandFunction();

            punchNavigationServiceMock.Verify(p => p.NavigateToStorePunchesPage(punchTimeStampParameter.Store), Times.Once);

        }

        [Test]
        public async Task TestAddImageViewModelImageSourceIsNullByTakePhoto()
        {
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            var mockPreferenceStorage = preferenceStorageMock.Object;
            var alertServiceMock = new Mock<IAlertService>();
            alertServiceMock.Setup(p => p.ShowAlert("请选择一种方式", "取消", null,
                "拍照", "从本地相册选取一张照片", null)).ReturnsAsync("拍照");
            var mockAlertService = alertServiceMock.Object;
            var pickPhotoServiceMock = new Mock<IPickPhotoService>();
            var mockPickPhotoService = pickPhotoServiceMock.Object;
            var punchViewPageViewModel = new PunchViewPageViewModel(mockPreferenceStorage, null, mockPickPhotoService,
                null, mockAlertService, null);
            var imageViewModel = new ImageViewModel(null, punchViewPageViewModel);

            await punchViewPageViewModel.AddImageViewModel(imageViewModel);

            preferenceStorageMock.Verify(p => p.Set("newPunch", false), Times.Once);
            alertServiceMock.Verify(p => p.ShowAlert("请选择一种方式", "取消", null,
                "拍照", "从本地相册选取一张照片", null), Times.Once);
            pickPhotoServiceMock.Verify(p => p.TakePhotoAsync(), Times.Once);
        }

        [Test]
        public async Task TestAddImageViewModelImageSourceIsNullByPickFromPhotoGallery()
        {
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            var mockPreferenceStorage = preferenceStorageMock.Object;
            var alertServiceMock = new Mock<IAlertService>();
            alertServiceMock.Setup(p => p.ShowAlert("请选择一种方式", "取消", null,
                "拍照", "从本地相册选取一张照片", null)).ReturnsAsync("从本地相册选取一张照片");
            var mockAlertService = alertServiceMock.Object;
            var pickPhotoServiceMock = new Mock<IPickPhotoService>();
            var mockPickPhotoService = pickPhotoServiceMock.Object;
            var punchViewPageViewModel = new PunchViewPageViewModel(mockPreferenceStorage, null, mockPickPhotoService,
                null, mockAlertService, null);
            var imageViewModel = new ImageViewModel(null, punchViewPageViewModel);

            await punchViewPageViewModel.AddImageViewModel(imageViewModel);

            preferenceStorageMock.Verify(p => p.Set("newPunch", false), Times.Once);
            alertServiceMock.Verify(p => p.ShowAlert("请选择一种方式", "取消", null,
                "拍照", "从本地相册选取一张照片", null), Times.Once);
            pickPhotoServiceMock.Verify(p => p.PickPhotoAsync(), Times.Once);
        }

        /// <summary>
        /// 删除后还剩余图片。
        /// </summary>

        [Test]
        public void TestRemoveImageViewModelImageViewModelCollectionNotEmptyAfter()
        {
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            var mockPreferenceStorage = preferenceStorageMock.Object;
            var collection = new ObservableCollection<ImageViewModel>();

            var punchViewPageViewModel = new PunchViewPageViewModel(mockPreferenceStorage, null, null,
                null, null, null);
            punchViewPageViewModel.ImageSource = new byte[1000];
            var im = new ImageViewModel(null, punchViewPageViewModel);
            collection.Add(im);
            punchViewPageViewModel.ImageSource = new byte[2000];
            punchViewPageViewModel.IsVisual = true;
            var im2 = new ImageViewModel(null, punchViewPageViewModel);
            collection.Add(im2);
            punchViewPageViewModel.ImageViewModelCollection = collection;
            punchViewPageViewModel.RemoveImageViewModel(im);
            Assert.IsTrue(punchViewPageViewModel.IsVisual);
        }

        /// <summary>
        /// 删除后不再剩余图片。
        /// </summary>
        [Test]
        public void TestRemoveImageViewModelImageViewModelCollectionIsEmptyAfter()
        {
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            var mockPreferenceStorage = preferenceStorageMock.Object;
            var collection = new ObservableCollection<ImageViewModel>();

            var punchViewPageViewModel = new PunchViewPageViewModel(mockPreferenceStorage, null, null,
                null, null, null);
            punchViewPageViewModel.ImageSource = new byte[1000];
            var im = new ImageViewModel(null, punchViewPageViewModel);
            collection.Add(im);
            punchViewPageViewModel.IsVisual = true;
            punchViewPageViewModel.ImageViewModelCollection = collection;
            punchViewPageViewModel.RemoveImageViewModel(im);
            Assert.IsFalse(punchViewPageViewModel.IsVisual);
        }
    }
}
